package com.vshop.controller.externalInterface;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.vshop.entity.comentity.PartnerPackage;
import com.vshop.entity.comentity.UserOrderPackage;
import com.vshop.entity.comentity.UserOrderPayment;
import com.vshop.entity.external.order.request.RequestOrder;
import com.vshop.entity.external.order.request.RequestOrderData;
import com.vshop.entity.external.order.request.RequestOrderTradeData;
import com.vshop.entity.external.order.response.ResponseOrder;
import com.vshop.entity.external.order.response.ResponseOrderData;
import com.vshop.entity.external.order.response.ResponseOrderTradeData;
import com.vshop.entity.interfacerequest.ExceptionRequest;
import com.vshop.entity.requestinterface.Constant;
import com.vshop.entity.requestinterface.usercardorder.orderpackage.request.OrderPackageRequest;
import com.vshop.entity.requestinterface.usercardorder.orderpackage.response.OrderPackageResponse;
import com.vshop.service.*;
import com.vshop.utils.HttpUtil;
import com.vshop.utils.Md5Encrypt;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * 专门用于外部接口来：订购套餐 ：获取单号下单
 *
 * @author lm
 * @date 2019/09/03
 */
@RestController
@Api(description = "下单")
@Slf4j
public class OrderServicePlanController {
    @Autowired
    private SequenceService sequenceService;

    @Autowired
    private PartnerInfoService partnerInfoService;

    @Autowired
    private PartnerPackageService partnerPackageService;

    @Autowired
    private UserOrderPackageService userOrderService;

    @Autowired
    private UserOrderPaymentService orderPaymentService;

    /**
     * 直接请求网关xml接口的地址
     */
    @Value("${iot.requestURI}")
    private String requestURI;

    @CrossOrigin
    @PostMapping(value = "order", produces = "application/json;charset=utf-8")
    @ResponseBody
    @ApiOperation(value = "下单", response = ResponseOrder.class)
    public String order(@ApiParam @RequestBody RequestOrder request) {
        // 1，生成流水号
        String connSeqNo = sequenceService.getPackageTaskNo();

        // 2,生成当前时间戳
        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String curtime = df.format(new Date());

        //3,定义要回复的内容
        String jsonString;

        ExceptionRequest utils = new ExceptionRequest();

        String requestStr = JSON.toJSONString(request);
        if (requestStr == null) {
            log.info("请求报文不合法:requestStr为空");
            jsonString = utils.dataWeiKong(connSeqNo, curtime);
            return jsonString;
        } else {
            log.info("前端请求报文是：" + requestStr);
            RequestOrder requestPackage = JSONArray.parseObject(requestStr, RequestOrder.class);
            String requestSign = requestPackage.getSign();
            if (requestPackage.getSign() == null) {
                log.info("请求报文不合法:sign为空");
                jsonString = utils.dataWeiKong(connSeqNo, curtime);
                return jsonString;
            } else {
                log.info("请求的签名是：" + requestSign);
                RequestOrderData requestData = requestPackage.getData();
                if (requestData == null) {
                    log.info("请求报文不合法:data为空");
                    jsonString = utils.dataWeiKong(connSeqNo, curtime);
                    return jsonString;
                } else {

                    String ConnSeqNo = requestData.getConnSeqNo();
                    String partnerCode = requestData.getPartnerCode();
                    String secret = partnerInfoService.getSecretByPartnerCode(partnerCode);
                    String tradeTime = requestData.getTradeTime();
                    String tradeType = requestData.getTradeType();
                    String version = requestData.getVersion();

                    if (requestData.getTradeData() == null || StringUtils.isBlank(ConnSeqNo) || StringUtils.isBlank(partnerCode) || StringUtils.isBlank(tradeTime) || StringUtils.isBlank(tradeType) || StringUtils.isBlank(version)) {
                        log.info("请求报文不合法:data参数不合法");
                        jsonString = utils.dataWeiKong(connSeqNo, curtime);
                        return jsonString;
                    } else {
                        ResponseOrderData data = null;

                        for (RequestOrderTradeData re : requestData.getTradeData()) {

                            String deviceCode = re.getDeviceCode();
                            String packageCode = re.getPackageCode();
                            String orderPeriod = re.getOrderPeriod();
                            String payAmount = re.getPayAmount();
                            String payCurrency = re.getPayCurrency();
                            String requestOrderId = re.getRequestOrderId();

                            if (StringUtils.isBlank(deviceCode) || StringUtils.isBlank(packageCode) || StringUtils.isBlank(orderPeriod) | StringUtils.isBlank(payAmount) || StringUtils.isBlank(payCurrency) || StringUtils.isBlank(payCurrency) || StringUtils.isBlank(requestOrderId)) {
                                log.info("请求报文不合法:tradeData参数不合法");
                                jsonString = utils.dataWeiKong(connSeqNo, curtime);
                                return jsonString;

                            } else {

                                String str = JSON.toJSONString(requestData);
                                String sign = utils.calculateSignature(str);
                                log.info("计算的签名是：" + sign);

                                if (!requestSign.equalsIgnoreCase(sign)) {
                                    jsonString = utils.signatureFailure(ConnSeqNo, tradeTime, tradeType, "0001", "签名有误，请确认签名！");
                                    return jsonString;
                                } else {

                                    int c = userOrderService.findCount(partnerCode, packageCode, requestOrderId);

                                    if (c > 0) {

                                        log.info("重复的下单请求:requestOrderId重复！");
                                        data = new ResponseOrderData();
                                        data.setConnSeqNo(connSeqNo);
                                        data.setPartnerCode(partnerCode);
                                        data.setTradeType(tradeType);
                                        data.setTradeTime(curtime);
                                        data.setRetCode("0203");
                                        data.setRetMsg("重复的下单请求");

                                    } else {
                                        //根据packageCode和partnerCode去查询相应信息
                                        List<PartnerPackage> packageList = partnerPackageService.getPackageListByCode(partnerCode, packageCode);

                                        if (packageList == null || packageList.size() <= 0) {

                                            log.info("根据packageCode和partnerCode去查询相应信息失败");
                                            data = new ResponseOrderData();
                                            data.setConnSeqNo(connSeqNo);
                                            data.setPartnerCode(partnerCode);
                                            data.setTradeType(tradeType);
                                            data.setTradeTime(curtime);
                                            data.setRetCode("0204");
                                            data.setRetMsg("当前企业无权订购此套餐");


                                        } else {
                                            for (PartnerPackage p : packageList) {
                                                //去下单
                                                OrderPackageRequest o = new OrderPackageRequest();
                                                o.setDeviceId(deviceCode);
                                                o.setGlobalOrder("0");
                                                o.setPackageName(p.getPackageName());
                                                o.setPackageCode(packageCode);
                                                o.setPackageType(p.getPackageType());
                                                o.setOrderPeriod(orderPeriod);
                                                o.setAmount(payAmount);
                                                o.setSecret(secret);
                                                o.setPartnerCode(partnerCode);

                                                String requestOrder = JSON.toJSONString(o);
                                                log.info("下单请求报文：" + requestOrder);
                                                String requestOrderUrl = requestURI + Constant.iot_orderPackage_2;
                                                // 发送post请求，并接收返回结果
                                                String requestOrderReturnStr = HttpUtil.httpPost(requestOrderUrl, requestOrder);
                                                log.info("下单响应报文：" + requestOrderReturnStr);
                                                OrderPackageResponse orderResponse = JSONArray.parseObject(requestOrderReturnStr, OrderPackageResponse.class);

                                                if (orderResponse != null) {

                                                    if (orderResponse.getRetCode().equals("0000") && orderResponse.getOrderId() != null) {

                                                        log.info("数据库没有这条记录：入库！");
                                                        //套餐订单表入库
                                                        UserOrderPackage order = new UserOrderPackage();
                                                        order.setPartnerCode(partnerCode);
                                                        order.setPartnerName(p.getPartnerName());
                                                        order.setDeviceCode(deviceCode);
                                                        order.setIccId(deviceCode);
                                                        order.setPackageCode(packageCode);
                                                        order.setPackageName(p.getPackageName());
                                                        order.setPackageType(p.getPackageType());
                                                        order.setBuyType(p.getBuyType());
                                                        order.setPriceType(p.getPriceType());
                                                        order.setSalesType(p.getSalesType());
                                                        order.setGlobalOrder("0");
                                                        order.setOrderPeriod(orderPeriod);
                                                        order.setRequestOrderId(requestOrderId);
                                                        order.setOrderNo(requestOrderId);
                                                        order.setPayId(orderResponse.getOrderId());
                                                        order.setPayAmount(payAmount);
                                                        order.setPayCurrency(payCurrency);
                                                        order.setPartnerScope("1");
                                                        order.setPackageFee(payAmount);
                                                        order.setExpressFee("0");
                                                        order.setCardFee("0");
                                                        userOrderService.insertUserHaveCard(order);

                                                        int count = orderPaymentService.findCountById(partnerCode, requestOrderId, orderResponse.getOrderId(), payAmount, payCurrency);
                                                        if (count <= 0) {
                                                            //支付表入库
                                                            UserOrderPayment payment = new UserOrderPayment();
                                                            payment.setPartnerCode(partnerCode);
                                                            payment.setRequestOrderId(requestOrderId);
                                                            payment.setPayId(orderResponse.getOrderId());
                                                            payment.setPayAmount(payAmount);
                                                            payment.setPayCurrency(payCurrency);
                                                            orderPaymentService.insertPaymentUserHaveCard(payment);
                                                        }

                                                        List<ResponseOrderTradeData> tradeDataList = new ArrayList<ResponseOrderTradeData>();
                                                        ResponseOrderTradeData tradeData = new ResponseOrderTradeData();

                                                        tradeData.setOrderId(orderResponse.getOrderId());
                                                        tradeDataList.add(tradeData);

                                                        data = new ResponseOrderData();
                                                        data.setConnSeqNo(connSeqNo);
                                                        data.setPartnerCode(partnerCode);
                                                        data.setTradeType(tradeType);
                                                        data.setTradeTime(curtime);
                                                        data.setRetCode("0000");
                                                        data.setRetMsg("成功");
                                                        data.setTradeData(tradeDataList);

                                                    } else {

                                                        data = new ResponseOrderData();
                                                        data.setConnSeqNo(connSeqNo);
                                                        data.setPartnerCode(partnerCode);
                                                        data.setTradeType(tradeType);
                                                        data.setTradeTime(curtime);
                                                        data.setRetCode("0205");
                                                        data.setRetMsg("获取单号失败");

                                                    }

                                                } else {

                                                    data = new ResponseOrderData();
                                                    data.setConnSeqNo(connSeqNo);
                                                    data.setPartnerCode(partnerCode);
                                                    data.setTradeType(tradeType);
                                                    data.setTradeTime(curtime);
                                                    data.setRetCode("9999");
                                                    data.setRetMsg("下单过程出现异常！");

                                                }


                                            }//循环拿套餐详细信息

                                        }


                                    }


                                }


                            }


                        }//循环里面是从请求中取数据的

                        ResponseOrder response = new ResponseOrder();
                        response.setData(data);
                        response.setSign(Md5Encrypt.md5(JSON.toJSONString(data)));

                        jsonString = JSON.toJSONString(response);
                        log.info("响应报文：" + jsonString);
                        return jsonString;

                    }
                }
            }
        }

    }
}
